package cn.itsource.ymcc.service.impl;

import cn.itsource.ymcc.constant.Constants;
import cn.itsource.ymcc.domain.Login;
import cn.itsource.ymcc.mapper.LoginMapper;
import cn.itsource.ymcc.result.JsonResult;
import cn.itsource.ymcc.service.ILoginService;
import cn.itsource.ymcc.util.AssertUtil;
import cn.itsource.ymcc.util.HttpUtil;
import cn.itsource.ymcc.util.jwt.JwtUtils;
import cn.itsource.ymcc.util.jwt.PayloadData;
import cn.itsource.ymcc.util.jwt.RsaUtils;
import cn.itsource.ymcc.vo.LoginVo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 登录表 服务实现类
 * </p>
 *
 * @author zongchangjiang
 * @since 2023-06-23
 */
@Service
public class LoginServiceImpl extends ServiceImpl<LoginMapper, Login> implements ILoginService {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Override
    public JsonResult loginIn(LoginVo loginVo) {
        //jsr303

        //去数据库查询数据  看有没有当前用户
        Login login = baseMapper.selectOne(new QueryWrapper<Login>()
                .eq("username", loginVo.getUsername())
                .eq("type", loginVo.getType()));
        if(login == null){
            return JsonResult.error("用户名或密码错误"); //有心人
        }
        //密码校验
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        AssertUtil.isTrue(bCryptPasswordEncoder.matches(loginVo.getPassword(),login.getPassword()),"用户名或密码错误");
        //登录成功
        Map<String, Object> stringObjectMap = accountLogin(login);
        return JsonResult.success().setData(stringObjectMap);
    }

    private static final String URL = "http://localhost:10086/oauth/token?client_id=admin&client_secret=123&grant_type=password&username=%s&redirect_uri=http://www.baidu.com&password=%s";

    @Override
    public Map<String,Object> loginSuccess(LoginVo loginDto) {
        //可以去做登录了   使用密码模式进行登录
        Map<String,Object> map = new HashMap<>();
        String passwordURL = String.format(URL, loginDto.getUsername(), loginDto.getPassword());

        String jsonStr = HttpUtil.sendPost(passwordURL, new HashMap<>());
        JSONObject jsonObject = JSON.parseObject(jsonStr);

        //3.封装到HashMap
        map.put("token", jsonObject.get("access_token"));
        map.put("refresh_token", jsonObject.get("refresh_token"));
        Object o = redisTemplate.opsForValue().get(Constants.KEY_OF_LOGIN + loginDto.getUsername());
        map.put("currentUser",o);
        return map;
    }

    //登录成功要返回的数据配置
    public Map<String,Object> accountLogin(Login login){
        Map<String,Object> map = new HashMap<>();
        try {
            //1.用户类型为0的时候（后台管理系统用户），连表查询当前登录用户拥有的权限和菜单  [今天先不做]
            //2.JWT工具类生成JWT字符串  私钥加密  公钥解密
            PrivateKey privateKey = RsaUtils
                    .getPrivateKey(FileCopyUtils
                            .copyToByteArray(this.getClass().getClassLoader().getResourceAsStream("hrm_auth_rsa")));
            //加密得到token
            PayloadData payloadData = new PayloadData();
            login.setPassword(null);    //置空密码，更安全
            payloadData.setLogin(login);
            String token = JwtUtils.generateTokenExpireInMinutes(payloadData, privateKey, 60*24);  //24小时过期

            //3.封装到HashMap
            map.put("token", token);
            map.put("currentUser", JSON.toJSONString(login));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //token  --- jwt
        //login 用户信息  不包含密码
        //menu  菜单信息  -- 当前用户能看的菜单 todo
        //auth  权限信息  -- 一堆路径而已  todo
        return map;
    }

//    public static void main(String[] args) {
//        String pwd = "123456";
//        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
//        String encode = bCryptPasswordEncoder.encode(pwd);
//        System.out.println(encode);
//        boolean matches = bCryptPasswordEncoder.matches("1236", encode);
//        System.out.println(matches);
//    }
}
